package com.pan.service.impl;

import com.pan.dao.category.CategoryDao;
import com.pan.dao.category.CategorySelectDao;
import com.pan.dao.category.CategoryUpdateDao;
import com.pan.entity.Category;
import com.pan.entity.Result;
import com.pan.enume.ResultEnum;
import com.pan.service.CategoryService;
import com.pan.tools.ConvertObject;
import com.pan.vo.CategoryCreateVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service("categoryService")
public class CategoryServiceImpl implements CategoryService {


    @Resource
    private CategorySelectDao categorySelectDao;

    @Resource
    private CategoryUpdateDao categoryUpdateDao;

    @Resource
    private CategoryDao categoryDao;

    @Override
    public Result<List<Category>> getAllParent(Long id){
        Category category = categorySelectDao.selectById(id);
        if (category==null){
            return new Result<>(ResultEnum.NOT_FOUND_ERROR);
        }
        List<Category> li = new ArrayList<>();
        while (!category.getPid().equals(0L)){
            li.add(category);
            Long pid = category.getPid();
            category = categorySelectDao.selectById(pid);
        }
        return new Result(ResultEnum.SUCCESS,li);
    }

    @Override
    public Result<List<Category>> getAllChild(Long id){
        List<Category> li = categorySelectDao.selectByPid(id);
        if (li==null || li.size()==0){
            return new Result<>(ResultEnum.NOT_FOUND_ERROR);
        }
        li = li.stream().sorted(Comparator.comparing(Category::getSort)).collect(Collectors.toList());
        return new Result<>(ResultEnum.SUCCESS,li);
    }

    @Override
    public Result<Boolean> isChild(Long id){
        List<Category> li = categorySelectDao.selectByPid(id);
        if (li==null||li.size()==0){
            return new Result<>(ResultEnum.SUCCESS,true);
        }
        return new Result<>(ResultEnum.SUCCESS,false);
    }

    @Override
    public Result<Category> selectById(Long id){
        Category category = categorySelectDao.selectById(id);
        if (category==null){
            return new Result<>(ResultEnum.NOT_FOUND_ERROR);
        }
        return new Result<>(ResultEnum.SUCCESS,category);
    }

    @Override
    public Result<List<Category>> selectChildById(Long id){
        List<Category> li = categorySelectDao.selectByPid(id);
        return new Result<>(ResultEnum.SUCCESS,li);
    }

    @Override
    public Result<List<Category>> selectByLevel1(){
        List<Category> li = categorySelectDao.selectByLevel(1);
        Result<List<Category>> result = new Result<>(ResultEnum.SUCCESS,li);
        return result;
    }


    @Transactional
    @Override
    public Result insert(String adminTicket, CategoryCreateVo categoryCreateVo){
        Long pid = categoryCreateVo.getPid();
        Category parentCategory = categorySelectDao.selectById(pid);
        if (parentCategory == null){
            return new Result(403,"父id不存在");
        }
        Category insertCategory = (Category) ConvertObject.convertObject(Category.class,categoryCreateVo);
        insertCategory.setLevel(parentCategory.getLevel()+1);
        insertCategory.setProductCount(0);
        insertCategory.setShowStatus((short) 1);
        insertCategory.setSort(0);
        insertCategory.setSort(0);
        Long id = categoryDao.insert(insertCategory);
        Result result = new Result(ResultEnum.SUCCESS,id);
        return result;
    }



    @Override
    public Result update(String adminTicket, Long id, Object updateValue, String updateName) {
        Class updateType = null;
        try {
            updateType = Category.class.getDeclaredField(updateName).getType();
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
        String updateMethodName = "update" + updateName.substring(0,1).toUpperCase()
                + updateName.substring(1);
        Method updateMethod = null;
        try {
            updateMethod = CategoryUpdateDao.class
                    .getMethod(updateMethodName,Long.class,updateType);
            updateMethod.invoke(categoryUpdateDao,id,updateValue);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        return new Result(ResultEnum.SUCCESS);
    }


}
